package com.lclz.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class JaxbUtil {

	private static final String CHARSET = "UTF-8";

	public static <T> String obj2xmlStr(T obj) throws Exception {
		if (obj == null) {
			throw new IllegalArgumentException("obj  is  null");
		}
		String str = null;
		StringWriter sw = new StringWriter();
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			m.setProperty(Marshaller.JAXB_ENCODING, CHARSET);
			m.marshal(obj, sw);
			str = sw.toString();
		} catch (Exception e) {
			throw new Exception("Exception", e);
		} finally {
			sw.close();
		}
		return str;
	}

	public static <T> void obj2xmlFile(T obj, String filePath) throws Exception {
		Writer writer = null;
		try {
			writer = new OutputStreamWriter(new FileOutputStream(filePath),
					CHARSET);
			obj2xmlWriter(obj, writer);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		} finally {
			if (writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					// Ignore the exception
				}
		}
	}

	public static <T> void obj2xmlWriter(T obj, Writer writer) throws Exception {
		if (obj == null || writer == null) {
			throw new IllegalArgumentException("obj or writer is null");
		}
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller m = context.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			m.setProperty(Marshaller.JAXB_ENCODING, CHARSET);
			m.marshal(obj, writer);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		}
	}

	public static <T> T xmlFile2Obj(Class<T> cls, String filepath)
			throws Exception {
		Reader reader = null;
		try {
			reader = new InputStreamReader(new FileInputStream(filepath),
					CHARSET);
			return xmlReader2Obj(cls, reader);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		} finally {
			if (reader != null)
				try {
					reader.close();
				} catch (IOException e) {
					// Ignore the exception
				}
		}
	}

	public static <T> T xmlFileStream2Obj(Class<T> cls, InputStream inputStream)
			throws Exception {
		Reader reader = null;
		try {
			reader = new InputStreamReader(inputStream);
			return xmlReader2Obj(cls, reader);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		} finally {
			if (reader != null)
				try {
					reader.close();
				} catch (IOException e) {
					// Ignore the exception
				}
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					// Ignore the exception
				}
			}
		}
	}

	public static <T> T xmlStr2Obj(Class<T> cls, String str) throws Exception {
		Reader reader = null;
		try {
			reader = new StringReader(str);
			return xmlReader2Obj(cls, reader);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		} finally {
			if (reader != null)
				try {
					reader.close();
				} catch (IOException e) {
					// Ignore the exception
				}
		}
	}

	@SuppressWarnings("unchecked")
	public static <T> T xmlReader2Obj(Class<T> cls, Reader reader)
			throws Exception {
		if (cls == null || reader == null) {
			throw new IllegalArgumentException("cls or reader is null");
		}
		JAXBContext context;
		try {
			context = JAXBContext.newInstance(cls);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			return (T) unmarshaller.unmarshal(reader);
		} catch (Exception e) {
			throw new Exception("Exception", e);
		}
	}
}
